﻿using agsXMPP.protocol.client;
using JClient;
using ScriptsAPI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace JBotAPI.Logs {
	public class LogCollection : ObservableCollection<Log> {
		public LogCollection(ConnectionProvider provider) {
			provider.OnAgentEnd += new agsXMPP.ObjectHandler(Provider_OnAgentEnd);
			provider.OnAgentItem += new agsXMPP.XmppClientConnection.AgentHandler(Provider_OnAgentItem);
			provider.OnAgentStart += new agsXMPP.ObjectHandler(Provider_OnAgentStart);
			provider.OnAuthError += new agsXMPP.XmppElementHandler(Provider_OnAuthError);
			provider.OnBinded += new agsXMPP.ObjectHandler(Provider_OnBinded);
			provider.OnClose += new agsXMPP.ObjectHandler(Provider_OnClose);
			provider.OnError += new agsXMPP.ErrorHandler(Provider_OnError);
			provider.OnIq += new agsXMPP.protocol.client.IqHandler(Provider_OnIq);
			provider.OnLogin += new agsXMPP.ObjectHandler(Provider_OnLogin);
			provider.OnMessage += new agsXMPP.protocol.client.MessageHandler(Provider_OnMessage);
			provider.OnPasswordChanged += new agsXMPP.ObjectHandler(Provider_OnPasswordChanged);
			provider.OnPresence += new agsXMPP.protocol.client.PresenceHandler(Provider_OnPresence);
			provider.OnReadSocketData += new agsXMPP.net.BaseSocket.OnSocketDataHandler(Provider_OnReadSocketData);
			provider.OnReadXml += new agsXMPP.XmlHandler(Provider_OnReadXml);
			provider.OnRegistered += new agsXMPP.ObjectHandler(Provider_OnRegistered);
			provider.OnRegisterError += new agsXMPP.XmppElementHandler(Provider_OnRegisterError);
			provider.OnRegisterInformation += new agsXMPP.protocol.iq.register.RegisterEventHandler(Provider_OnRegisterInformation);
			provider.OnRosterEnd += new agsXMPP.ObjectHandler(Provider_OnRosterEnd);
			provider.OnRosterItem += new agsXMPP.XmppClientConnection.RosterHandler(Provider_OnRosterItem);
			provider.OnRosterStart += new agsXMPP.ObjectHandler(Provider_OnRosterStart);
			provider.OnSaslEnd += new agsXMPP.ObjectHandler(Provider_OnSaslEnd);
			provider.OnSaslStart += new agsXMPP.sasl.SaslEventHandler(Provider_OnSaslStart);
			provider.OnSocketError += new agsXMPP.ErrorHandler(Provider_OnSocketError);
			provider.OnStreamError += new agsXMPP.XmppElementHandler(Provider_OnStreamError);
			provider.OnWriteSocketData += new agsXMPP.net.BaseSocket.OnSocketDataHandler(Provider_OnWriteSocketData);
			provider.OnWriteXml += new agsXMPP.XmlHandler(Provider_OnWriteXml);
			provider.OnXmppConnectionStateChanged += new agsXMPP.XmppConnectionStateHandler(Provider_OnXmppConnectionStateChanged);
			//provider.OnXmppError += new XmppElementHandler(Provider_OnXmppError);
		}

		#region Provider events
		#region Zdarzenia Połączenia
		private void Provider_OnXmppConnectionStateChanged(object sender, agsXMPP.XmppConnectionState state) {
			this.Add("OnXmppConnectionStateChanged", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnSaslStart(object sender, agsXMPP.sasl.SaslEventArgs args) {
			this.Add("OnSaslStart", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnSaslEnd(object sender) {
			this.Add("OnSaslEnd", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnBinded(object sender) {
			this.Add("OnBinded", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnLogin(object sender) {
			this.Add("OnLogin", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnAgentEnd(object sender) {
			this.Add("OnAgentEnd", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnAgentItem(object sender, agsXMPP.protocol.iq.agent.Agent agent) {
			this.Add("OnAgentItem", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnAgentStart(object sender) {
			this.Add("OnAgentStart", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnRosterStart(object sender) {
			this.Add("OnRosterStart", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnRosterItem(object sender, agsXMPP.protocol.iq.roster.RosterItem item) {
			this.Add("OnRosterItem", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnRosterEnd(object sender) {
			this.Add("OnRosterEnd", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnClose(object sender) {
			this.Add("OnClose", LogFlags.XMPP, LogType.Info);
		}
		#endregion
		#region Zdarzenia danych
		private void Provider_OnReadSocketData(object sender, byte[ ] data, int count) {
			this.Add("OnReadSocketData", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnWriteSocketData(object sender, byte[ ] data, int count) {
			this.Add("OnWriteSocketData", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnReadXml(object sender, string xml) {
			this.Add("OnReadXml", LogFlags.XMPP, LogType.Info);
			if (xml != null && xml != "")
				this.Add("Received:\n" + xml, LogFlags.XMPPXML, LogType.Info);
		}
		private void Provider_OnWriteXml(object sender, string xml) {
			this.Add("OnWriteXml", LogFlags.XMPP, LogType.Info);
			if (xml != null && xml != "")
				this.Add("Sended:\n" + xml, LogFlags.XMPPXML, LogType.Info);
		}
		#endregion
		#region Zdarzenia wywołane przez sieć
		private void Provider_OnIq(object sender, agsXMPP.protocol.client.IQ iq) {
			this.Add("OnIq", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnMessage(object sender, agsXMPP.protocol.client.Message msg) {
			this.Add("OnMessage", LogFlags.XMPP, LogType.Info);
			if (msg.From.User != null && msg.From.User != "") {
				this.Add(String.Format("Message from {0}", msg.From.User), LogFlags.XMPP, LogType.Info);
			} else {
				this.Add(String.Format("Message from {0}", msg.From.ToString( )), LogFlags.XMPP, LogType.Info);
			}
		}
		private void Provider_OnPresence(object sender, agsXMPP.protocol.client.Presence pres) {
			this.Add("OnPresence", LogFlags.XMPP, LogType.Info);
			if (pres.Type == PresenceType.available || pres.Type == PresenceType.invisible || pres.Type == PresenceType.unavailable) {
				if (pres.From.User == pres.To.User && pres.From.Server == pres.To.Server) {
				} else if (pres.From.User != null && pres.From.User != "") {
					this.Add("Contact " + String.Format("{0}@{1}", pres.From.User, pres.From.Server) + " is " + pres.getDescStr(), LogFlags.XMPP, LogType.Info);
				} else {
					this.Add("Transport " + pres.From.Server + " is " + pres.getDescStr( ), LogFlags.XMPP, LogType.Info);
				}
			}
		}
		private void Provider_OnRegistered(object sender) {
			this.Add("OnRegistered", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnRegisterInformation(object sender, agsXMPP.protocol.iq.register.RegisterEventArgs args) {
			this.Add("OnRegisterInformation", LogFlags.XMPP, LogType.Info);
		}
		private void Provider_OnPasswordChanged(object sender) {
			this.Add("OnPasswordChanged", LogFlags.XMPP, LogType.Info);
		}
		#endregion
		#region Zdarzenia typu Error!
		private void Provider_OnError(object sender, System.Exception ex) {
			this.Add("OnError - " + ex.Message, LogFlags.XMPP, LogType.Error);
		}
		private void Provider_OnSocketError(object sender, System.Exception ex) {
			this.Add("OnSocketError - " + ex.Message, LogFlags.XMPP, LogType.Error);
		}
		private void Provider_OnStreamError(object sender, agsXMPP.Xml.Dom.Element e) {
			this.Add("OnStreamError - " + e.ToString( ), LogFlags.XMPP, LogType.Error);
		}
		/*private void Provider_OnXmppError(object sender, agsXMPP.Xml.Dom.Element e) {
			this.Add("OnXmppError - " + e.ToString( ), LogFlags.XMPP, LogType.Error);
		}*/
		private void Provider_OnAuthError(object sender, agsXMPP.Xml.Dom.Element e) {
			this.Add("OnAuthError - " + e.ToString( ), LogFlags.XMPP, LogType.Error);
			//this.Add(String.Format("Unable to authorize with server {0}.", Me.jid.Server), LogFlags.XMPP, LogType.Error);
		}
		private void Provider_OnRegisterError(object sender, agsXMPP.Xml.Dom.Element e) {
			this.Add("OnRegisterError - " + e.ToString( ), LogFlags.XMPP, LogType.Error);
		}
		#endregion
		#endregion

		#region Events
		public delegate void NewLogEvent(object sender, NewLogEventArgs e);
		public event NewLogEvent LogAdded;
		#endregion

		#region Main functions
		public void Add(string text, LogFlags flag, LogType type) {
			this.Insert(0, new Log( ) {
				text = text,
				flag = flag,
				type = type
			});
			if (LogAdded != null) {
				NewLogEventArgs NLEA = new NewLogEventArgs(text, flag, type);
				//LogAdded.Method.Invoke(LogAdded.Target, new object[ ] { this, NLEA });
				//LogAdded.Invoke(this, NLEA);
				LogAdded(this, NLEA);
			}
		}
		#endregion
	}
}